package cn.wolfcode.util;

import cn.wolfcode.domain.Log;
import cn.wolfcode.domain.SystemDictionary;
import cn.wolfcode.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Date;

@Component //把当前类注入到spring容器中
@Aspect    //把当前类标识为一个切面供容器读取
public class AopConfig {

    /**
     * 指定切入点
     * 对贴有自定义注解@RequiredPermission的方法，进行切面
     */
    @Pointcut("@annotation(cn.wolfcode.util.RequiredPermission)")
    private void useMethod() {}

    @Autowired
    private LogMapper logMapper;
    /**
     * 对切入点进行增强
     */
    @Around(value = "useMethod()")
    //ProceedingJoinPoint 连接点对象
    public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = new Object();
        Log log = new Log();
        long start = System.currentTimeMillis();
        //设置用户名
        log.setUsername(UserContext.getCurrentUser().getUsername());

        //获取目标对象的字节码对象
        Class<?> targetCls = proceedingJoinPoint.getTarget().getClass();
        //获取方法签名(方法名加参数)
        MethodSignature signature = (MethodSignature)proceedingJoinPoint.getSignature();//MethodSignature继承Signature
        //通过放射获取方法
        Method method = targetCls.getDeclaredMethod(signature.getName(), signature.getParameterTypes());
        //获取目标方法上的注解的用户操作名称
        String operation = method.getAnnotation(RequiredPermission.class).name();
        //设置用户操作
        log.setOperation(operation);
        //获取类全名
        String className = method.getDeclaringClass().getName();
        //获取方法名
        String methodName = method.getName();
        //设置请求方法
        log.setMethod(className+methodName);
        //获取方法参数
        Object[] args = proceedingJoinPoint.getArgs();
        //设置请求参数
        log.setParameter(Arrays.toString(args));
        //获取ip地址
        InetAddress localHost = InetAddress.getLocalHost();
        String ip = localHost.getHostAddress();
        log.setIp(ip);
        //设置执行时间(没有异常)
        long requestTime = System.currentTimeMillis();
        log.setWorkTime(new Date(requestTime-start));
        try {
            //执行处理方法（执行控制器中的方法）*****
            result = proceedingJoinPoint.proceed();
            //设置操作时间
            long operationTime = System.currentTimeMillis();
            log.setOperationTime(new Date(operationTime-start));
            //设置操作结果
            log.setResult(true);
            //result是方法的返回值，直接return回去就会返回给springmvc处理
            return result;
        }catch (RuntimeException e){
            //设置操作时间
            long operationTime = System.currentTimeMillis();
            log.setOperationTime(new Date(operationTime-start));
            //设置操作结果
            log.setResult(false);
            //设置错误信息
            log.setMessage(e.getMessage());
            //result是方法的返回值，直接return回去就会返回给springmvc处理
            return result;
        }finally {
            logMapper.insert(log);
        }
    }


}